package com.mk.exnotice.handler;

import com.mk.exnotice.pojos.ExceptionNotice;
import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import com.mk.exnotice.event.ExceptionNoticeEvent;
import com.mk.exnotice.properties.ExceptionNoticeProperties;
import org.springframework.context.ApplicationEventPublisher;
import java.util.LinkedList;
import java.util.List;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ExceptionHandler {

    private ApplicationEventPublisher applicationEventPublisher;

    private ExceptionNoticeProperties properties;

    public ExceptionNotice createNotice(RuntimeException ex,String url, String method, Object[] args) {
        // 若报错信息包含需要排除的异常，则不推送
        if (containsException(properties, ex)) {
            return null;
        }
        ExceptionNotice exceptionNotice = new ExceptionNotice(ex, properties,url, method, args);
        applicationEventPublisher.publishEvent(new ExceptionNoticeEvent(this, exceptionNotice));
        return exceptionNotice;
    }



    private boolean containsException(ExceptionNoticeProperties properties, RuntimeException exception) {
        List<Class<? extends Throwable>> thisEClass = getAllExceptionClazz(exception);
        List<Class<? extends Exception>> list = properties.getExcludeExceptions();
        for (Class<? extends Exception> clazz : list) {
            if (thisEClass.stream().anyMatch(c -> clazz.isAssignableFrom(c)))
                return true;
        }
        return false;
    }

    private List<Class<? extends Throwable>> getAllExceptionClazz(RuntimeException exception) {
        List<Class<? extends Throwable>> list = new LinkedList<Class<? extends Throwable>>();
        list.add(exception.getClass());
        Throwable cause = exception.getCause();
        while (cause != null) {
            list.add(cause.getClass());
            cause = cause.getCause();
        }
        return list;
    }
}
